import { Injectable, HttpException, HttpStatus } from '@nestjs/common';
import { Repository } from 'typeorm';
import { InjectRepository } from '@nestjs/typeorm';
import { RouteEntity } from './route.entity';
import { Between, Not, TreeRepository, getManager, Brackets } from 'typeorm';
import * as dayjs from 'dayjs';
// import { skip } from 'rxjs/operators';
type captcha = {
  key: string;
  captcha: string;
  validTime?: string;
};

@Injectable()
export class RouteService {
  constructor(
    @InjectRepository(RouteEntity)
    private readonly routeRepository: Repository<RouteEntity>,
  ) {}

  async getRouteList(param) {
    return await this.routeRepository.find({ where: param });
  }
  async getRouteTreeList(param) {
    const {
      current,
      pageSize,
      noPagination,
      orderParam,
      createDateRange,
      accessIds,
      ...restParam
    } = param;

    let where = {
      ...restParam,
      createDate: Between(createDateRange?.[0], createDateRange?.[1]),
    };
    if (!createDateRange) {
      delete where.createDate;
    }

    //排序逻辑
    const order = {};
    Object.keys(orderParam || {}).map(item => {
      order[`route.${item}`] = orderParam[item];
    });
    const manager = getManager();
    return await manager
      .getTreeRepository(RouteEntity).findTrees({relations:['access']})
    // const manager = getManager();
    // let data = await manager
    //   .getTreeRepository(RouteEntity)
    //   .createDescendantsQueryBuilder('route', 'routeClosure', new RouteEntity())
    //   .leftJoinAndSelect('route.access', 'access')
    //   .leftJoinAndSelect('route.children', 'children')
    //   .leftJoinAndSelect('children.access', 'children.access')
    //   .leftJoinAndSelect('children.children', 'children.children')
    //   // .leftJoinAndSelect('children.access', 'children.access')
    //   .where(where)
    //   .andWhere('route.parent is null')
    //   .andWhere(qb => {
    //     const subQuery = qb
    //       .subQuery()
    //       .select('route.id')
    //       .from(RouteEntity, 'route')
    //       .leftJoin('route.access', 'access')
    //       .andWhere(
    //         new Brackets(qb => {
    //           if (accessIds) {
    //             return qb.where('access.id IN (:...accessIds)', { accessIds });
    //           }
    //         }),
    //       )
    //       .getQuery();
    //     return 'route.id IN ' + subQuery;
    //   })
    //   .orderBy(order)
    //   .skip(noPagination ? undefined : (current - 1) * pageSize)
    //   .take(noPagination ? undefined : pageSize)
    //   // .getSql()
    //   // console.log(data);
    //   .getManyAndCount();
    // return { data: data[0], total: data[1], current, pageSize };
  }

  async getRouteTree(param) {
    const manager = getManager();

    return await manager
      .getTreeRepository(RouteEntity)
      .createDescendantsQueryBuilder('route', 'routeClosure', new RouteEntity())
      .leftJoinAndSelect('route.access', 'access')
      .leftJoinAndSelect('route.children', 'children')
      .leftJoinAndSelect('children.access', 'children.access')
      .leftJoinAndSelect('children.children', 'children.children')
      .where({})
      .getMany();
  }
  async getRoute(param) {
    return await this.routeRepository
      .createQueryBuilder('route')
      .leftJoinAndSelect('route.access', 'access')
      .where(param)
      .getOne();
  }
  async saveRoute(param) {
    const { pid, access = [], ...restParam } = param;
    const manager = getManager();
    let route = new RouteEntity();
    Object.assign(route, restParam);
    route.access = access.map(id => {
      return { id };
    });
    !route.id && (route.createDate = dayjs().format('YYYY-MM-DD HH:mm:ss'));
    if (pid) {
      const root = new RouteEntity();
      root.id = pid;
      route.parent = root;
      return await manager.save(route);
    } else {
      return await manager.save(route);
    }
  }
  async delRouteList(param) {
    const { idList } = param;
    let data = await this.routeRepository.findByIds(idList);
    return await this.routeRepository.remove(data);
  }
}
